(*DONT_TOUCH = "TRUE"*)
module uart_transceiver #(
    parameter mux_num = 1536,
    parameter work_clk_freq = 100000000
)(
    input wire clk,
    input wire rst_n,
    input wire rx,
    output wire tx,

    input [15:0] result_bram_r_data,
    output reg [$clog2(mux_num)-1:0] result_bram_r_addr,
    output reg result_bram_r_en,

    output reg busy,
    output reg [$clog2(mux_num)-1:0] mux_index
);

    // UART RX
    wire [7:0] rx_data;
    wire rx_valid;

    uart_rx #(
        .BAUD_RATE(115200),
        .CLOCK_FREQ(work_clk_freq)
    ) u_rx (
        .clk(clk),
        .rst_n(rst_n),
        .rx(rx),
        .data(rx_data),
        .valid(rx_valid)
    );

    // UART TX
    reg tx_start;
    reg [7:0] tx_data;
    wire tx_busy;

    uart_tx #(
        .BAUD_RATE(115200),
        .CLOCK_FREQ(work_clk_freq)
    ) u_tx (
        .clk(clk),
        .rst_n(rst_n),
        .uart_tx_en(tx_start),
        .uart_tx_data(tx_data),
        .uart_txd(tx),
        .uart_tx_busy(tx_busy)
    );

    // FSM 控制
    reg [2:0] state;
    localparam IDLE   = 3'd0;
    localparam READ   = 3'd1;
    localparam SEND_H = 3'd2;
    localparam SEND_WAIT = 3'd3;
    localparam SEND_L = 3'd4;

    reg [15:0] data_buf;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= IDLE;
            busy <= 0;
            result_bram_r_addr <= 0;
            result_bram_r_en <= 0;
            mux_index <= 0;
            tx_start <= 0;
            tx_data <= 8'd0;
            data_buf <= 16'd0;
        end else begin
            tx_start <= 0; // 默认不触发发送

            case (state)
                IDLE: begin
                    busy <= 0;
                    result_bram_r_en <= 0;
                    if (rx_valid && rx_data == "r") begin
                        busy <= 1;
                        mux_index <= 0;
                        result_bram_r_addr <= 0;
                        result_bram_r_en <= 1;
                        state <= READ;
                    end
                end

                READ: begin
                    // BRAM 数据在下一个周期稳定
                    data_buf <= result_bram_r_data;
                    state <= SEND_H;
                end

                SEND_H: begin
                    if (!tx_busy) begin
                        tx_data <= data_buf[15:8]; // 先发高字节 data_buf[15:8]; 
                        tx_start <= 1;
                        state <= SEND_WAIT;
                    end
                    else begin
                        state <= SEND_H;
                    end
                end

                SEND_WAIT: begin
                    state <= SEND_L;
                end

                SEND_L: begin
                    if (!tx_busy) begin
                        tx_data <= data_buf[7:0]; // 再发低字节 data_buf[7:0]
                        tx_start <= 1;

                        // 是否发送完全部
                        if (mux_index == mux_num-1) begin
                            state <= IDLE;
                        end else begin
                            mux_index <= mux_index + 1;
                            result_bram_r_addr <= mux_index + 1;
                            state <= READ;
                        end
                    end
                    else begin
                        state <= SEND_L;
                    end
                end

            endcase
        end
    end

endmodule
